package org.com.behavioralPattern.strategyPattern;

/**
 * 策略模式应用场景
 * ■ 多个类只是在算法或行为上稍有不同的场景。
 * ■ 算法需要自由切换的场景。
 * ■ 需要屏蔽算法规则的场景
 * @author Jonny
 * @version 1.0
 * @Description:
 * @date 2021/4/27 14:16
 */

/**
 *优点
 * ■ 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族，
 * 恰当地使用继承可以把公共的代码移到父类中，从而避免代码重复。
 * ■ 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为，如果不用策略模式，
 * 那么使用算法或行为的环境类就可能会有一些子类，每一个子类提供一个不同的算法或行为。
 * 但是，这样算法或行为的使用者就和算法本身混在一起，从而不可能再独立演化。
 * ■ 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护，
 * 它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起，
 * 统统列在一个多重转移语句里面，这比使用继承的办法还要原始和落后。
 *缺点
 * ■ 客户端必须知道所有的策略类，并自行决定使用哪一个策略类。
 * 这就意味着客户端必须理解这些算法的区别，以便适时选择恰当的算法类，
 * 即策略模式只适用于客户端知道所有的算法或行为的情况。
 * ■ 策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保持到客户端里面，
 * 而将策略类设计成可共享的，这样策略类实例可以被不同客户端使用。可以使用享元模式来减少对象的数量。
 */
public class ContextClient {
    private DiscountStrategy ds;
    public ContextClient(DiscountStrategy ds){
        this.ds=ds;
    }

    public double contextcalDisc(){
        return ds.calculateDiscount();
    }

    public static void main(String[] args) {
        ContextClient context0=new ContextClient(new NoDiscountStrategy(48.6,20));
        System.out.println("0折扣："+context0.contextcalDisc());

        ContextClient context1=new ContextClient(new FixDiscountStrategy(46,60));
        System.out.println("固定折扣："+context1.contextcalDisc());

        ContextClient context2=new ContextClient(new PercentageDiscountStrategy(30,40));
        System.out.println("15%折扣："+context2.contextcalDisc());
    }
}
